﻿namespace Jsl.FxCop
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using Microsoft.FxCop.Sdk;

    /// <summary>
    /// A visitor that is more simple to use than the <see cref="BinaryReadOnlyVisitor"/>.
    /// </summary>
    /// <remarks>
    /// The problem with <see cref="BinaryReadOnlyVisitor"/> is that you have to derive off of it and override methods
    /// to set your visitors. This isn't a problem if you are only calling Visit once for one purpose. It gets complicated
    /// when you want to do two or more completely different things. This helper class allows you to set up your visitors
    /// however you want without creating a derived class and overriding the virtual visit methods. Simply call
    /// <see cref="AddVisitor"/> and then <see cref="BinaryReadOnlyVisitor.Visit"/> and your visitor action will be called.
    /// </remarks>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Cci", Justification = "That's what MS calls it!")]
    public sealed class CciVisitor : BinaryReadOnlyVisitor
    {
		private Action<object> allNodeVisitor;
        private readonly Dictionary<Type, Action<object>> visitors = new Dictionary<Type, Action<object>>();

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="CciVisitor"/> class.
        /// </summary>
        public CciVisitor()
        {
        }
        #endregion Constructors

        #region Public Methods
        /// <summary>
        /// Adds the visitor that will be called for ALL nodes.
        /// </summary>
        /// <param name="visitor">The visitor.</param>
        /// <returns>The <see cref="CciVisitor"/>.</returns>
        public CciVisitor AddAllNodeVisitor(Action<object> visitor)
        {
            if (this.allNodeVisitor != null)
            {
                throw new InvalidOperationException("There can be only one all node visitor");
            }

            this.allNodeVisitor = visitor;

            return this;
        }

        /// <summary>
        /// Adds the visitor.
        /// </summary>
        /// <typeparam name="TNode">The type of the node.</typeparam>
        /// <param name="visitor">The visitor.</param>
        /// <returns>The <see cref="CciVisitor"/>.</returns>
        public CciVisitor AddVisitor<TNode>(Action<TNode> visitor)
        {
            this.visitors.Add(typeof(TNode), (object node) => visitor((TNode)node));

            return this;
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.AddressDereference"/> Cci element.
        /// </summary>
        /// <param name="dereference">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitAddressDereference(Microsoft.FxCop.Sdk.AddressDereference dereference)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.AddressDereference>(dereference);

            base.VisitAddressDereference(dereference);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.AssemblyNode"/> Cci element.
        /// </summary>
        /// <param name="assembly">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitAssembly(Microsoft.FxCop.Sdk.AssemblyNode assembly)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.AssemblyNode>(assembly);

            base.VisitAssembly(assembly);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.AssemblyReference"/> Cci element.
        /// </summary>
        /// <param name="assemblyReference">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitAssemblyReference(Microsoft.FxCop.Sdk.AssemblyReference assemblyReference)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.AssemblyReference>(assemblyReference);

            base.VisitAssemblyReference(assemblyReference);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.AssignmentStatement"/> Cci element.
        /// </summary>
        /// <param name="assignment">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitAssignmentStatement(Microsoft.FxCop.Sdk.AssignmentStatement assignment)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.AssignmentStatement>(assignment);

            base.VisitAssignmentStatement(assignment);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.AttributeNode"/> Cci element.
        /// </summary>
        /// <param name="attribute">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitAttributeConstructor(Microsoft.FxCop.Sdk.AttributeNode attribute)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.AttributeNode>(attribute);

            base.VisitAttributeConstructor(attribute);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.AttributeNode"/> Cci element.
        /// </summary>
        /// <param name="attribute">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitAttributeNode(Microsoft.FxCop.Sdk.AttributeNode attribute)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.AttributeNode>(attribute);

            base.VisitAttributeNode(attribute);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.AttributeNodeCollection"/> Cci element.
        /// </summary>
        /// <param name="attributes">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitAttributes(Microsoft.FxCop.Sdk.AttributeNodeCollection attributes)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.AttributeNodeCollection>(attributes);

            base.VisitAttributes(attributes);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.BinaryExpression"/> Cci element.
        /// </summary>
        /// <param name="binaryExpression">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitBinaryExpression(Microsoft.FxCop.Sdk.BinaryExpression binaryExpression)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.BinaryExpression>(binaryExpression);

            base.VisitBinaryExpression(binaryExpression);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Block"/> Cci element.
        /// </summary>
        /// <param name="block">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitBlock(Microsoft.FxCop.Sdk.Block block)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Block>(block);

            base.VisitBlock(block);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.BlockCollection"/> Cci element.
        /// </summary>
        /// <param name="blocks">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitBlocks(Microsoft.FxCop.Sdk.BlockCollection blocks)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.BlockCollection>(blocks);

            base.VisitBlocks(blocks);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Branch"/> Cci element.
        /// </summary>
        /// <param name="branch">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitBranch(Microsoft.FxCop.Sdk.Branch branch)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Branch>(branch);

            base.VisitBranch(branch);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.CatchNode"/> Cci element.
        /// </summary>
        /// <param name="catchNode">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitCatch(Microsoft.FxCop.Sdk.CatchNode catchNode)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.CatchNode>(catchNode);

            base.VisitCatch(catchNode);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.CatchNodeCollection"/> Cci element.
        /// </summary>
        /// <param name="catchClauses">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitCatchHandlers(Microsoft.FxCop.Sdk.CatchNodeCollection catchClauses)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.CatchNodeCollection>(catchClauses);

            base.VisitCatchHandlers(catchClauses);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ClassNode"/> Cci element.
        /// </summary>
        /// <param name="classType">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitClass(Microsoft.FxCop.Sdk.ClassNode classType)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ClassNode>(classType);

            base.VisitClass(classType);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Construct"/> Cci element.
        /// </summary>
        /// <param name="construct">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitConstruct(Microsoft.FxCop.Sdk.Construct construct)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Construct>(construct);

            base.VisitConstruct(construct);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ConstructArray"/> Cci element.
        /// </summary>
        /// <param name="constructArray">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitConstructArray(Microsoft.FxCop.Sdk.ConstructArray constructArray)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ConstructArray>(constructArray);

            base.VisitConstructArray(constructArray);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.DelegateNode"/> Cci element.
        /// </summary>
        /// <param name="delegateNode">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitDelegateNode(Microsoft.FxCop.Sdk.DelegateNode delegateNode)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.DelegateNode>(delegateNode);

            base.VisitDelegateNode(delegateNode);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.EndFilter"/> Cci element.
        /// </summary>
        /// <param name="endFilter">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitEndFilter(Microsoft.FxCop.Sdk.EndFilter endFilter)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.EndFilter>(endFilter);

            base.VisitEndFilter(endFilter);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.EndFinally"/> Cci element.
        /// </summary>
        /// <param name="endFinally">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitEndFinally(Microsoft.FxCop.Sdk.EndFinally endFinally)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.EndFinally>(endFinally);

            base.VisitEndFinally(endFinally);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.EnumNode"/> Cci element.
        /// </summary>
        /// <param name="enumNode">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitEnumNode(Microsoft.FxCop.Sdk.EnumNode enumNode)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.EnumNode>(enumNode);

            base.VisitEnumNode(enumNode);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.EventNode"/> Cci element.
        /// </summary>
        /// <param name="eventMember">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitEvent(Microsoft.FxCop.Sdk.EventNode eventMember)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.EventNode>(eventMember);

            base.VisitEvent(eventMember);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Expression"/> Cci element.
        /// </summary>
        /// <param name="expression">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitExpression(Microsoft.FxCop.Sdk.Expression expression)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Expression>(expression);

            base.VisitExpression(expression);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ExpressionCollection"/> Cci element.
        /// </summary>
        /// <param name="expressions">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitExpressions(Microsoft.FxCop.Sdk.ExpressionCollection expressions)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ExpressionCollection>(expressions);

            base.VisitExpressions(expressions);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ExpressionStatement"/> Cci element.
        /// </summary>
        /// <param name="statement">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitExpressionStatement(Microsoft.FxCop.Sdk.ExpressionStatement statement)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ExpressionStatement>(statement);

            base.VisitExpressionStatement(statement);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.FaultHandler"/> Cci element.
        /// </summary>
        /// <param name="faultHandler">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitFaultHandler(Microsoft.FxCop.Sdk.FaultHandler faultHandler)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.FaultHandler>(faultHandler);

            base.VisitFaultHandler(faultHandler);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Field"/> Cci element.
        /// </summary>
        /// <param name="field">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitField(Microsoft.FxCop.Sdk.Field field)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Field>(field);

            base.VisitField(field);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Filter"/> Cci element.
        /// </summary>
        /// <param name="filter">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitFilter(Microsoft.FxCop.Sdk.Filter filter)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Filter>(filter);

            base.VisitFilter(filter);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.FinallyNode"/> Cci element.
        /// </summary>
        /// <param name="finallyClause">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitFinally(Microsoft.FxCop.Sdk.FinallyNode finallyClause)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.FinallyNode>(finallyClause);

            base.VisitFinally(finallyClause);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Indexer"/> Cci element.
        /// </summary>
        /// <param name="indexer">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitIndexer(Microsoft.FxCop.Sdk.Indexer indexer)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Indexer>(indexer);

            base.VisitIndexer(indexer);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.InstanceInitializer"/> Cci element.
        /// </summary>
        /// <param name="constructor">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitInstanceInitializer(Microsoft.FxCop.Sdk.InstanceInitializer constructor)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.InstanceInitializer>(constructor);

            base.VisitInstanceInitializer(constructor);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.InterfaceNode"/> Cci element.
        /// </summary>
        /// <param name="interfaceType">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitInterface(Microsoft.FxCop.Sdk.InterfaceNode interfaceType)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.InterfaceNode>(interfaceType);

            base.VisitInterface(interfaceType);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.InterfaceNode"/> Cci element.
        /// </summary>
        /// <param name="interfaceType">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitInterfaceReference(Microsoft.FxCop.Sdk.InterfaceNode interfaceType)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.InterfaceNode>(interfaceType);

            base.VisitInterfaceReference(interfaceType);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.InterfaceCollection"/> Cci element.
        /// </summary>
        /// <param name="interfaceReferences">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitInterfaceReferences(Microsoft.FxCop.Sdk.InterfaceCollection interfaceReferences)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.InterfaceCollection>(interfaceReferences);

            base.VisitInterfaceReferences(interfaceReferences);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Literal"/> Cci element.
        /// </summary>
        /// <param name="literal">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitLiteral(Microsoft.FxCop.Sdk.Literal literal)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Literal>(literal);

            base.VisitLiteral(literal);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Local"/> Cci element.
        /// </summary>
        /// <param name="local">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitLocal(Microsoft.FxCop.Sdk.Local local)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Local>(local);

            base.VisitLocal(local);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.MemberBinding"/> Cci element.
        /// </summary>
        /// <param name="memberBinding">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitMemberBinding(Microsoft.FxCop.Sdk.MemberBinding memberBinding)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.MemberBinding>(memberBinding);

            base.VisitMemberBinding(memberBinding);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.MemberCollection"/> Cci element.
        /// </summary>
        /// <param name="members">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitMembers(Microsoft.FxCop.Sdk.MemberCollection members)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.MemberCollection>(members);

            base.VisitMembers(members);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Method"/> Cci element.
        /// </summary>
        /// <param name="method">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitMethod(Microsoft.FxCop.Sdk.Method method)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Method>(method);

            base.VisitMethod(method);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.MethodCall"/> Cci element.
        /// </summary>
        /// <param name="call">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitMethodCall(Microsoft.FxCop.Sdk.MethodCall call)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.MethodCall>(call);

            base.VisitMethodCall(call);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ModuleNode"/> Cci element.
        /// </summary>
        /// <param name="module">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitModule(Microsoft.FxCop.Sdk.ModuleNode module)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ModuleNode>(module);

            base.VisitModule(module);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ModuleReference"/> Cci element.
        /// </summary>
        /// <param name="moduleReference">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitModuleReference(Microsoft.FxCop.Sdk.ModuleReference moduleReference)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ModuleReference>(moduleReference);

            base.VisitModuleReference(moduleReference);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.NamedArgument"/> Cci element.
        /// </summary>
        /// <param name="namedArgument">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitNamedArgument(Microsoft.FxCop.Sdk.NamedArgument namedArgument)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.NamedArgument>(namedArgument);

            base.VisitNamedArgument(namedArgument);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Parameter"/> Cci element.
        /// </summary>
        /// <param name="parameter">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitParameter(Microsoft.FxCop.Sdk.Parameter parameter)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Parameter>(parameter);

            base.VisitParameter(parameter);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ParameterCollection"/> Cci element.
        /// </summary>
        /// <param name="parameters">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitParameters(Microsoft.FxCop.Sdk.ParameterCollection parameters)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ParameterCollection>(parameters);

            base.VisitParameters(parameters);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.PropertyNode"/> Cci element.
        /// </summary>
        /// <param name="property">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitProperty(Microsoft.FxCop.Sdk.PropertyNode property)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.PropertyNode>(property);

            base.VisitProperty(property);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ReturnNode"/> Cci element.
        /// </summary>
        /// <param name="returnInstruction">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitReturn(Microsoft.FxCop.Sdk.ReturnNode returnInstruction)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ReturnNode>(returnInstruction);

            base.VisitReturn(returnInstruction);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.SecurityAttribute"/> Cci element.
        /// </summary>
        /// <param name="attribute">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitSecurityAttribute(Microsoft.FxCop.Sdk.SecurityAttribute attribute)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.SecurityAttribute>(attribute);

            base.VisitSecurityAttribute(attribute);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.SecurityAttributeCollection"/> Cci element.
        /// </summary>
        /// <param name="attributes">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitSecurityAttributes(Microsoft.FxCop.Sdk.SecurityAttributeCollection attributes)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.SecurityAttributeCollection>(attributes);

            base.VisitSecurityAttributes(attributes);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.StatementCollection"/> Cci element.
        /// </summary>
        /// <param name="statements">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitStatements(Microsoft.FxCop.Sdk.StatementCollection statements)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.StatementCollection>(statements);

            base.VisitStatements(statements);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.StaticInitializer"/> Cci element.
        /// </summary>
        /// <param name="classConstructor">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitStaticInitializer(Microsoft.FxCop.Sdk.StaticInitializer classConstructor)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.StaticInitializer>(classConstructor);

            base.VisitStaticInitializer(classConstructor);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Struct"/> Cci element.
        /// </summary>
        /// <param name="valueType">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitStruct(Microsoft.FxCop.Sdk.Struct valueType)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Struct>(valueType);

            base.VisitStruct(valueType);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.SwitchInstruction"/> Cci element.
        /// </summary>
        /// <param name="switchInstruction">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitSwitchInstruction(Microsoft.FxCop.Sdk.SwitchInstruction switchInstruction)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.SwitchInstruction>(switchInstruction);

            base.VisitSwitchInstruction(switchInstruction);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.Expression"/> Cci element.
        /// </summary>
        /// <param name="expression">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTargetExpression(Microsoft.FxCop.Sdk.Expression expression)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.Expression>(expression);

            base.VisitTargetExpression(expression);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TernaryExpression"/> Cci element.
        /// </summary>
        /// <param name="expression">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTernaryExpression(Microsoft.FxCop.Sdk.TernaryExpression expression)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TernaryExpression>(expression);

            base.VisitTernaryExpression(expression);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.This"/> Cci element.
        /// </summary>
        /// <param name="thisVariable">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitThis(Microsoft.FxCop.Sdk.This thisVariable)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.This>(thisVariable);

            base.VisitThis(thisVariable);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.ThrowNode"/> Cci element.
        /// </summary>
        /// <param name="throwInstruction">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitThrow(Microsoft.FxCop.Sdk.ThrowNode throwInstruction)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.ThrowNode>(throwInstruction);

            base.VisitThrow(throwInstruction);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TryNode"/> Cci element.
        /// </summary>
        /// <param name="tryClause">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTry(Microsoft.FxCop.Sdk.TryNode tryClause)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TryNode>(tryClause);

            base.VisitTry(tryClause);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TypeModifier"/> Cci element.
        /// </summary>
        /// <param name="typeModifier">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTypeModifier(Microsoft.FxCop.Sdk.TypeModifier typeModifier)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TypeModifier>(typeModifier);

            base.VisitTypeModifier(typeModifier);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TypeNode"/> Cci element.
        /// </summary>
        /// <param name="type">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTypeNode(Microsoft.FxCop.Sdk.TypeNode type)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TypeNode>(type);

            base.VisitTypeNode(type);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TypeNodeCollection"/> Cci element.
        /// </summary>
        /// <param name="types">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTypeNodes(Microsoft.FxCop.Sdk.TypeNodeCollection types)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TypeNodeCollection>(types);

            base.VisitTypeNodes(types);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TypeNode"/> Cci element.
        /// </summary>
        /// <param name="typeParameter">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTypeParameter(Microsoft.FxCop.Sdk.TypeNode typeParameter)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TypeNode>(typeParameter);

            base.VisitTypeParameter(typeParameter);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TypeNodeCollection"/> Cci element.
        /// </summary>
        /// <param name="typeParameters">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTypeParameters(Microsoft.FxCop.Sdk.TypeNodeCollection typeParameters)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TypeNodeCollection>(typeParameters);

            base.VisitTypeParameters(typeParameters);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TypeNode"/> Cci element.
        /// </summary>
        /// <param name="type">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTypeReference(Microsoft.FxCop.Sdk.TypeNode type)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TypeNode>(type);

            base.VisitTypeReference(type);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.TypeNodeCollection"/> Cci element.
        /// </summary>
        /// <param name="typeReferences">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitTypeReferences(Microsoft.FxCop.Sdk.TypeNodeCollection typeReferences)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.TypeNodeCollection>(typeReferences);

            base.VisitTypeReferences(typeReferences);
        }

        /// <summary>
        /// Visits the <see cref="Microsoft.FxCop.Sdk.UnaryExpression"/> Cci element.
        /// </summary>
        /// <param name="unaryExpression">The Cci element.</param>
        [EditorBrowsable(EditorBrowsableState.Never)]
        public override void VisitUnaryExpression(Microsoft.FxCop.Sdk.UnaryExpression unaryExpression)
        {
            this.CallVisitor<Microsoft.FxCop.Sdk.UnaryExpression>(unaryExpression);

            base.VisitUnaryExpression(unaryExpression);
        }        
        #endregion Public Methods

        #region Private Methods
        private void CallVisitor<TNode>(TNode node)
        {
            if (this.allNodeVisitor != null)
            {
                this.allNodeVisitor(node);
            }

            Action<object> visitor;
            if (this.visitors.TryGetValue(typeof(TNode), out visitor))
            {
                visitor(node);
            }
        }
        #endregion Private Methods
    }
}